#include "Model/WeeklyCalendarRule.hpp"
#include "CalendarRuleTests.hpp"
#include <boost/test/auto_unit_test.hpp>

namespace
{

using namespace Model;

BOOST_AUTO_TEST_CASE( testWeekDayOperations)
{
	WeeklyCalendarRule rule;
	BOOST_CHECK( !rule.isWeekDayIncluded( 1));
	BOOST_CHECK( !rule.isWeekDayIncluded( 2));
	BOOST_CHECK( !rule.isWeekDayIncluded( 3));
	BOOST_CHECK( !rule.isWeekDayIncluded( 4));
	BOOST_CHECK( !rule.isWeekDayIncluded( 5));
	BOOST_CHECK( !rule.isWeekDayIncluded( 6));
	BOOST_CHECK( !rule.isWeekDayIncluded( 7));

	rule.addWeekDay( 1);
	BOOST_CHECK( rule.isWeekDayIncluded( 1));
	BOOST_CHECK( !rule.isWeekDayIncluded( 2));
	BOOST_CHECK( !rule.isWeekDayIncluded( 3));
	BOOST_CHECK( !rule.isWeekDayIncluded( 4));
	BOOST_CHECK( !rule.isWeekDayIncluded( 5));
	BOOST_CHECK( !rule.isWeekDayIncluded( 6));
	BOOST_CHECK( !rule.isWeekDayIncluded( 7));

	rule.addWeekDay( 4);
	BOOST_CHECK( rule.isWeekDayIncluded( 1));
	BOOST_CHECK( !rule.isWeekDayIncluded( 2));
	BOOST_CHECK( !rule.isWeekDayIncluded( 3));
	BOOST_CHECK( rule.isWeekDayIncluded( 4));
	BOOST_CHECK( !rule.isWeekDayIncluded( 5));
	BOOST_CHECK( !rule.isWeekDayIncluded( 6));
	BOOST_CHECK( !rule.isWeekDayIncluded( 7));

	rule.removeWeekDay( 2);
	BOOST_CHECK( rule.isWeekDayIncluded( 1));
	BOOST_CHECK( !rule.isWeekDayIncluded( 2));
	BOOST_CHECK( !rule.isWeekDayIncluded( 3));
	BOOST_CHECK( rule.isWeekDayIncluded( 4));
	BOOST_CHECK( !rule.isWeekDayIncluded( 5));
	BOOST_CHECK( !rule.isWeekDayIncluded( 6));
	BOOST_CHECK( !rule.isWeekDayIncluded( 7));

	rule.removeWeekDay( 1);
	BOOST_CHECK( !rule.isWeekDayIncluded( 1));
	BOOST_CHECK( !rule.isWeekDayIncluded( 2));
	BOOST_CHECK( !rule.isWeekDayIncluded( 3));
	BOOST_CHECK( rule.isWeekDayIncluded( 4));
	BOOST_CHECK( !rule.isWeekDayIncluded( 5));
	BOOST_CHECK( !rule.isWeekDayIncluded( 6));
	BOOST_CHECK( !rule.isWeekDayIncluded( 7));

	rule.removeWeekDay( 4);
	BOOST_CHECK( !rule.isWeekDayIncluded( 1));
	BOOST_CHECK( !rule.isWeekDayIncluded( 2));
	BOOST_CHECK( !rule.isWeekDayIncluded( 3));
	BOOST_CHECK( !rule.isWeekDayIncluded( 4));
	BOOST_CHECK( !rule.isWeekDayIncluded( 5));
	BOOST_CHECK( !rule.isWeekDayIncluded( 6));
	BOOST_CHECK( !rule.isWeekDayIncluded( 7));

}

// ---------------------------------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE( testOneWeek)
{
	// | S M T W T F S |
	//     X   X   X
	// |^^^^^^^^^^^^^^^|

	WeeklyCalendarRule rule;
	rule.addWeekDay( 2);
	rule.addWeekDay( 4);
	rule.addWeekDay( 6);

	Calendar::PeriodSet results;
	rule.getPeriods( Calendar::Time( Calendar::Date( 2008, 12, 21)), Calendar::Time( Calendar::Date( 2008, 12, 28)), results);
	BOOST_REQUIRE_EQUAL( 3, results.size());
	Calendar::PeriodSet::const_iterator resultI = results.begin();
	CHECK_TIME_INTERVAL( Calendar::Time( Calendar::Date( 2008, 12, 22)), Calendar::Time( Calendar::Date( 2008, 12, 23)), *resultI); ++resultI;
	CHECK_TIME_INTERVAL( Calendar::Time( Calendar::Date( 2008, 12, 24)), Calendar::Time( Calendar::Date( 2008, 12, 25)), *resultI); ++resultI;
	CHECK_TIME_INTERVAL( Calendar::Time( Calendar::Date( 2008, 12, 26)), Calendar::Time( Calendar::Date( 2008, 12, 27)), *resultI);
}

// ---------------------------------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE( testConsecutiveDays)
{
	// | S M T W T F S |
	//     X X X
	// |^^^^^^^^^^^^^^^|

	WeeklyCalendarRule rule;
	rule.addWeekDay( 2);
	rule.addWeekDay( 3);
	rule.addWeekDay( 4);

	Calendar::PeriodSet results;
	rule.getPeriods( Calendar::Time( Calendar::Date( 2008, 12, 21)), Calendar::Time( Calendar::Date( 2008, 12, 28)), results);
	BOOST_REQUIRE_EQUAL( 1, results.size());
	Calendar::PeriodSet::const_iterator resultI = results.begin();
	CHECK_TIME_INTERVAL( Calendar::Time( Calendar::Date( 2008, 12, 22)), Calendar::Time( Calendar::Date( 2008, 12, 25)), *resultI);
}

// ---------------------------------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE( testWeekend)
{
	// | S M T W T F S | S M T W T F S |
	//   X           X   X           X
	// |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|
	WeeklyCalendarRule rule;
	rule.addWeekDay( 1);
	rule.addWeekDay( 7);

	Calendar::PeriodSet results;
	rule.getPeriods( Calendar::Time( Calendar::Date( 2008, 12, 21)), Calendar::Time( Calendar::Date( 2009, 01, 04)), results);
	BOOST_REQUIRE_EQUAL( 3, results.size());
	Calendar::PeriodSet::const_iterator resultI = results.begin();
	CHECK_TIME_INTERVAL( Calendar::Time( Calendar::Date( 2008, 12, 21)), Calendar::Time( Calendar::Date( 2008, 12, 22)), *resultI); ++resultI;
	CHECK_TIME_INTERVAL( Calendar::Time( Calendar::Date( 2008, 12, 27)), Calendar::Time( Calendar::Date( 2008, 12, 29)), *resultI); ++resultI;
	CHECK_TIME_INTERVAL( Calendar::Time( Calendar::Date( 2009, 01, 03)), Calendar::Time( Calendar::Date( 2009, 01, 04)), *resultI);
}

} // namespace
